﻿using DBCompare.Config;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using zTool;
namespace DBCompare
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            CheckForIllegalCrossThreadCalls = false;
        }

        private void btnCompare_Click(object sender, EventArgs e)
        {

        }

        public void Disply(ref RichTextBox rtb, string strInput, Color fontColor)
        {
            int p1 = rtb.TextLength;  //取出未添加时的字符串长度。 
            rtb.AppendText(strInput);  //保留每行的所有颜色。 //  rtb.Text += strInput + "\n";  //添加时，仅当前行有颜色。 
            int p2 = strInput.Length;  //取出要添加的文本的长度 
            rtb.Select(p1, p2);        //选中要添加的文本 
            rtb.SelectionColor = fontColor;  //设置要添加的文本的字体色 
            //rtb.Refresh(); 
        }

        private void TaskComp()
        {

            /*获取两个数据库中的所有表,进行比较表是否异同*/
            var igorneTable = AppCfg.IgorneTable;//.Split(',').ToList();
            var l1 = AppCfg.IgorneTable==""? DBServices.GetTableInfoByConnStr(AppCfg.ConnStrOne) : DBServices.GetTableInfoByConnStr(AppCfg.ConnStrOne).Where(x => !x.TableName.Contains(igorneTable)).ToList();
            var l2 = AppCfg.IgorneTable == ""? DBServices.GetTableInfoByConnStr(AppCfg.ConnStrTwo) : DBServices.GetTableInfoByConnStr(AppCfg.ConnStrTwo).Where(x => !x.TableName.Contains(igorneTable)).ToList();
            var r1 = l1.Where(x => !l2.Select(y => y.TableName).Contains(x.TableName)).ToList();
            var r2 = l2.Where(x => !l1.Select(y => y.TableName).Contains(x.TableName)).ToList();
            txtDiffTable.Text = "";
            //黑色
            Disply(ref txtDiffTable, "DB1 Have,DB2 No Have  --> Tables:\n", Color.Black);
            //红色
            r1.ForEach(x =>
            {
                Disply(ref txtDiffTable, $"{x.TableName}\n", Color.Red);
            });
            //黑色
            Disply(ref txtDiffTable, "DB2 Have,DB1 No Have  --> Tables:\n", Color.Black);
            //红色
            r2.ForEach(x =>
            {
                Disply(ref txtDiffTable, $"{x.TableName}\n", Color.Red);
            });

            /*
             * 开始比较字段不同的地方
             * 假设结果1 为主表,
             */
            string total = l1.Count.ToString();
            int beginI = 0;
            lblLog.Text = "Comparing..."; tsCompare.Enabled = false;
            foreach (var x in l1)
            {
                var sameTable = l2.Where(y => y.TableName == x.TableName)?.FirstOrDefault();
                if (sameTable != null)//这个表如果两个数据都有去比较字段
                {
                    var c1 = DBServices.GetColInfosByTableId(AppCfg.ConnStrOne, x.TableId);//数据库1的表字段
                    var c2 = DBServices.GetColInfosByTableId(AppCfg.ConnStrTwo, sameTable.TableId);//数据库2的表字段
                    var cr1 = c1.Where(o => !c2.Select(y => y.ColName).Contains(o.ColName)).ToList();//字段差异
                    var cr2 = c2.Where(o => !c1.Select(y => y.ColName).Contains(o.ColName)).ToList();//字段差异
                    if (cr1.Any())
                    {
                        Disply(ref txtDiffTable, $"DB2 【{x.TableName}】No Fields:\n", Color.Black);

                        cr1.ForEach(Q =>
                        {
                            Disply(ref txtDiffTable, $"{Q.ColName}\n", Color.Red);
                        });
                    }
                    if (cr2.Any())
                    {
                        Disply(ref txtDiffTable, $"DB1 【{x.TableName}】No Fields:\n", Color.Black);
                        cr2.ForEach(Q =>
                        {
                            Disply(ref txtDiffTable, $"{Q.ColName}\n", Color.Red);
                        });
                    }
                }
                beginI++;
                lblJd.Text = $"{beginI}/{total}";
            }
            lblLog.Text = "Compared oj8k."; tsCompare.Enabled = true;
        }

        private void 基本配置ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            new FrmBaseConfig().ShowDialog();
        }

        private void tsCompare_Click(object sender, EventArgs e)
        {
            if (!new DbHelper(AppCfg.ConnStrOne).GetConnState())
            {
                MessageBox.Show("DB1 Can't Open");
                return;
            }
            if (!new DbHelper(AppCfg.ConnStrTwo).GetConnState())
            {
                MessageBox.Show("DB2 Can't Open");
                return;
            }
            Task.Run(() =>
            {
                TaskComp();
            });
        }

        private void tsSaveCompareResult_Click(object sender, EventArgs e)
        {
            string path = Path.Combine(Application.StartupPath, "CompareResult");
            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);
            string filePath = Path.Combine(path, "CompareResult_" + DateTime.Now.ToString("yyy_MM_dd_HH_mm_ss") + ".txt");
            File.WriteAllText(filePath, txtDiffTable.Text, Encoding.UTF8);
            Process.Start(path);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            var path = Path.Combine(Application.StartupPath, "CoreCfg.dll");
            try
            {
                if (File.Exists(path))
                {
                    var jsonStr = File.ReadAllText(path, Encoding.UTF8);
                    var jobj = jsonStr.ToJObject();
                    AppCfg.ConnStrOne = jobj["ConnStrOne"].ToString();
                    AppCfg.ConnStrTwo = jobj["ConnStrTwo"].ToString();
                    AppCfg.IgorneTable = jobj["IgorneTable"].ToString();
                }
            }
            catch (Exception ex)
            {
                File.Delete(path);
                MessageBox.Show("Initialization Application Error,Exit");
                Application.Restart();
            }
        }
    }
}
